home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
ddj0897.zip
/
CCDBMS.ZIP
/
DBARRAY.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-03-18
|
6KB
|
217 lines
// =================================================================
// Dbarray.cpp
// =================================================================
// Harold Kasperink / John Dekker
// Dr. Dobb's Journal 1997
// =================================================================
// Multithreaded Database Array Singleton class
// =================================================================
#include <iostream.h>
#include "dbarray.h"
// Fill singleton array with initial value
CArrayDbase * CArrayDbase::g_pDbArray = 0;
CMutex CArrayDbase::g_mtxArray;
////////////////////////////////////////////////////////////////////
// CArrayDbase::CArrayDbase
////////////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////////////
CArrayDbase::CArrayDbase(int nNrConnections, const char *szUsr, const char *szPsswd, const char *szDB)
{
m_nNrDbases = 0;
m_pszUsr = 0;
m_pszPsswd = 0;
m_pszDb = 0;
m_nCurCon = 0;
m_bPrint = FALSE;
memset(m_nDbUsage, 0, MAX_NR_DBASES*sizeof(int));
// Check if database array object allready there
if (g_pDbArray != 0)
return;
// Check parameter
if (nNrConnections < 1)
nNrConnections = 1;
if (nNrConnections > MAX_NR_DBASES)
nNrConnections = MAX_NR_DBASES;
ConnectInfo(szUsr, szPsswd, szDB);
// Create databases
for (int i=0; i<nNrConnections; i++) {
m_pDbases[i] = new CDbase;
if (m_pDbases[i] == 0) {
// Not succeedeed
cout << "No Connections\n";
}
m_nNrDbases = nNrConnections;
}
// Create database threads
for (i=0; i<nNrConnections; i++) {
m_pDbases[i]->ConnectInfo(m_pszUsr, m_pszPsswd, m_pszDb);
m_pDbases[i]->Create();
}
// Everything OK
g_pDbArray = this;
}
////////////////////////////////////////////////////////////////////
// CArrayDbase::~CArrayDbase
////////////////////////////////////////////////////////////////////
// Destructor
////////////////////////////////////////////////////////////////////
CArrayDbase::~CArrayDbase()
{
DeleteConnectInfo();
m_bPrint = FALSE;
if (this == g_pDbArray) {
Lock();
g_pDbArray = 0;
Unlock();
}
for (int i=0; i<m_nNrDbases; i++) {
if (m_pDbases[i] != 0)
delete m_pDbases[i];
}
}
////////////////////////////////////////////////////////////////////
// CArrayDbase::ConnectInfo
////////////////////////////////////////////////////////////////////
// Set connect information strings
////////////////////////////////////////////////////////////////////
void CArrayDbase::ConnectInfo(const char *szUsr, const char *szPsswd, const char *szDB)
{
DeleteConnectInfo();
if (szUsr != 0)
m_pszUsr = strdup(szUsr);
if (szPsswd != 0)
m_pszPsswd = strdup(szPsswd);
if (szDB != 0)
m_pszDb = strdup(szDB);
}
////////////////////////////////////////////////////////////////////
// CArrayDbase::DeleteConnectInfo
////////////////////////////////////////////////////////////////////
// free connect information strings
////////////////////////////////////////////////////////////////////
void CArrayDbase::DeleteConnectInfo()
{
if (m_pszUsr != 0)
delete m_pszUsr;
if (m_pszPsswd != 0)
delete m_pszPsswd;
if (m_pszDb != 0)
delete m_pszDb;
}
////////////////////////////////////////////////////////////////////
// CArrayDbase::~ReserveDbase
////////////////////////////////////////////////////////////////////
// Get free database connection from array object
////////////////////////////////////////////////////////////////////
CDbase *CArrayDbase::ReserveDbase()
{
// If no database array object
if (g_pDbArray == 0)
return 0;
Lock();
// Get dbases from database array object
CDbase ** pDbases = g_pDbArray->m_pDbases;
int nNrDbases = g_pDbArray->m_nNrDbases;
int * pCurCon = &g_pDbArray->m_nCurCon;
int * nDbUsage = g_pDbArray->m_nDbUsage;
// Loop for find a free database connection
while (TRUE) {
for (int i=0; i<nNrDbases; i++) {
// Database array object is delete in mean-time
if (g_pDbArray == 0)
return 0;
// Find free database
if (pDbases[i]->TryLock()) {
nDbUsage[i] += 1;
Unlock();
return pDbases[i];
}
}
// All connections are occupied, see take inuse one
CDbase *pDb = pDbases[*pCurCon];
nDbUsage[*pCurCon] += 1;
// Increase next inuse counter
*pCurCon += 1;
if (*pCurCon >= nNrDbases)
*pCurCon = 0;
Unlock();
pDb->Lock();
return pDb;
}
}
////////////////////////////////////////////////////////////////////
// CArrayDbase::~ReleaseDbase
////////////////////////////////////////////////////////////////////
// Release allocated database
////////////////////////////////////////////////////////////////////
void CArrayDbase::ReleaseDbase(CDbase &dbase)
{
// If no database array object
if (g_pDbArray == 0)
return;
Lock();
// Get dbases from database array object
CDbase ** pDbases = g_pDbArray->m_pDbases;
int nNrDbases = g_pDbArray->m_nNrDbases;
int * nDbUsage = g_pDbArray->m_nDbUsage;
// Search for database
for (int i=0; i<nNrDbases; i++) {
// Find free database
if (pDbases[i] == &dbase) {
nDbUsage[i] -= 1;
dbase.Unlock();
Unlock();
return;
}
}
Unlock();
}
////////////////////////////////////////////////////////////////////
// CArrayDbase::Lock
////////////////////////////////////////////////////////////////////
void CArrayDbase::Lock()
{
g_mtxArray.Lock();
}
////////////////////////////////////////////////////////////////////
// CArrayDbase::UnLock
////////////////////////////////////////////////////////////////////
void CArrayDbase::Unlock()
{
g_mtxArray.Unlock();
}